﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Psm.PubSub.Serialization;
using Psm.PubSub.StateCache;
using Psm.Util;

namespace Psm.PubSub.Messaging
{
    public class QueryMessage : PubSubMessage
    {
        private IDictionary<string, string> _filters;

        public string Topic { get { return Schema == null ? null : Schema.Topic; } }
        public Schema Schema { get; private set; }
        public IDictionary<string, string> Filters
        {
            get
            {
                return _filters;
            }
        }

        public bool IsClosed
        {
            get
            {
                return false;
            }
        }

        public override PubSubMessageType MessageType
        {
            get { return PubSubMessageType.QUERY_MESSAGE; }
        }


        public QueryMessage(Schema schema)
        {
            _filters = new Dictionary<string, string>();
            this.Schema = schema;
        }

        public QueryMessage(ByteBuffer payload)
        {
            _filters = new Dictionary<string, string>();
            MessageDeserializer serializer = new MessageDeserializer(payload);
            string topic = serializer.GetField();
            Schema = SchemaCollection.AllSchemas[topic];
            while (serializer.HasMore())
            {
                string name; string value;
                serializer.GetTuple(out name, out value);
                _filters.Add(Schema.Fields[int.Parse(name)].Name, value);
            }
        }

        public override  bool Serialize(ByteBuffer buffer)
        {
            MessageSerializer serializer = new MessageSerializer(PubSubMessageType.QUERY_MESSAGE, buffer);
            if( !serializer.AppendField(Topic) ) return false;
            foreach (string key in _filters.Keys)
            {
                if (!serializer.AppendTuple(Schema.GetField(key).Index.ToString(), _filters[key])) return false;
            }
            return true;
        }
    }
}
